home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #2 / Ham Radio 2000 - Volume 2.iso / HAMV2 / TCP_IP / TNOS230S / AX25HDR.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-08-29  |  2.8 KB  |  115 lines

  1. /* AX25 header conversion routines
  2.  * Copyright 1991 Phil Karn, KA9Q
  3.  */
  4. #include "global.h"
  5. #include "mbuf.h"
  6. #include "ax25.h"
  7.  
  8. #if !defined(_lint)
  9. static char rcsid[] OPTIONAL = "$Id: ax25hdr.c,v 1.7 1996/08/29 12:11:16 root Exp root $";
  10. #endif
  11.  
  12.  
  13. /* Convert a host-format AX.25 header into a mbuf ready for transmission */
  14. struct mbuf *
  15. htonax25 (hdr, data)
  16. register struct ax25 *hdr;
  17. struct mbuf *data;
  18. {
  19. struct mbuf *bp;
  20. register unsigned char *cp;
  21. register int16 i;
  22.  
  23.     if (hdr == (struct ax25 *) NULL || hdr->ndigis > MAXDIGIS)
  24.         return NULLBUF;
  25.  
  26.     /* Allocate space for return buffer */
  27.     i = (int16) (AXALEN * (2 + hdr->ndigis));
  28.     if ((bp = pushdown (data, i)) == NULLBUF)
  29.         return NULLBUF;
  30.  
  31.     /* Now convert */
  32.     cp = bp->data;        /* cp -> dest field */
  33.  
  34.     /* Generate destination field */
  35.     memcpy (cp, hdr->dest, AXALEN);
  36.     if (hdr->cmdrsp == LAPB_COMMAND)
  37.         cp[ALEN] |= C;    /* Command frame sets C bit in dest */
  38.     else
  39.         cp[ALEN] &= ~C;
  40.     cp[ALEN] &= ~E;        /* Dest E-bit is always off */
  41.  
  42.     cp += AXALEN;        /* cp -> source field */
  43.  
  44.     /* Generate source field */
  45.     memcpy (cp, hdr->source, AXALEN);
  46.     if (hdr->cmdrsp == LAPB_RESPONSE)
  47.         cp[ALEN] |= C;
  48.     else
  49.         cp[ALEN] &= ~C;
  50.     /* Set E bit on source address if no digis */
  51.     if (hdr->ndigis == 0) {
  52.         cp[ALEN] |= E;
  53.         return bp;
  54.     }
  55.     cp += AXALEN;        /* cp -> first digi field */
  56.  
  57.     /* All but last digi get copied with E bit off */
  58.     for (i = 0; i < hdr->ndigis; i++) {
  59.         memcpy (cp, hdr->digis[i], AXALEN);
  60.         if (i < hdr->ndigis - 1)
  61.             cp[ALEN] &= ~E;
  62.         else
  63.             cp[ALEN] |= E;    /* Last digipeater has E bit set */
  64.         if (i < hdr->nextdigi) {
  65.             cp[ALEN] |= REPEATED;
  66.         } else
  67.             cp[ALEN] &= ~REPEATED;
  68.         cp += AXALEN;    /* cp -> next digi field */
  69.     }
  70.     return bp;
  71. }
  72.  
  73.  
  74. /* Convert a network-format AX.25 header into a host format structure
  75.  * Return -1 if error, number of addresses if OK
  76.  */
  77. int
  78. ntohax25 (hdr, bpp)
  79. register struct ax25 *hdr;    /* Output structure */
  80. struct mbuf **bpp;
  81. {
  82. register char *axp;
  83.  
  84.     if (pullup (bpp, (unsigned char *) hdr->dest, AXALEN) < AXALEN)
  85.         return -1;
  86.  
  87.     if (pullup (bpp, (unsigned char *) hdr->source, AXALEN) < AXALEN)
  88.         return -1;
  89.  
  90.     /* Process C bits to get command/response indication */
  91.     if ((hdr->source[ALEN] & C) == (hdr->dest[ALEN] & C))
  92.         hdr->cmdrsp = LAPB_UNKNOWN;
  93.     else if (hdr->source[ALEN] & C)
  94.         hdr->cmdrsp = LAPB_RESPONSE;
  95.     else
  96.         hdr->cmdrsp = LAPB_COMMAND;
  97.  
  98.     hdr->ndigis = 0;
  99.     hdr->nextdigi = 0;
  100.     if (hdr->source[ALEN] & E)
  101.         return 2;    /* No digis */
  102.  
  103.     /* Count and process the digipeaters */
  104.     axp = hdr->digis[0];
  105.     while (hdr->ndigis < MAXDIGIS && pullup (bpp, (unsigned char *) axp, AXALEN) == AXALEN) {
  106.         hdr->ndigis++;
  107.         if (axp[ALEN] & REPEATED)
  108.             hdr->nextdigi++;
  109.         if (axp[ALEN] & E)    /* Last one */
  110.             return hdr->ndigis + 2;
  111.         axp += AXALEN;
  112.     }
  113.     return -1;        /* Too many digis */
  114. }
  115.